package seatiger.tomcat.catalina.startup;

import org.apache.commons.digester.Digester;
import org.apache.commons.digester.RuleSetBase;
import seatiger.tomcat.catalina.Container;
import seatiger.tomcat.catalina.core.StandardWrapper;
import seatiger.tomcat.catalina.deploy.FilterDef;
import seatiger.tomcat.catalina.deploy.FilterMap;

/**
 * 解析web.xml的rule
 *
 * 会提前手动压入 一个context对象，在栈底
 */
public class WebRuleSet extends RuleSetBase {
    @Override
    public void addRuleInstances(Digester digester) {
        //servlet相关规则
        servletRule(digester);
        //filter相关
        filterRule(digester);
    }

    private void filterRule(Digester digester) {
        digester.addObjectCreate("web-app/filter", FilterDef.class);
        digester.addSetNext("web-app/filter","addFilterDef",FilterDef.class.getName());
        digester.addCallMethod("web-app/filter/filter-class","setFilterClass", 0);
        digester.addCallMethod("web-app/filter/filter-name","setFilterName", 0);
        digester.addObjectCreate("web-app/filter-mapping",FilterMap.class);
        digester.addSetNext("web-app/filter-mapping","addFilterMap", FilterMap.class.getName());
        digester.addCallMethod("web-app/filter-mapping/filter-name","setFilterName", 0);
        digester.addCallMethod("web-app/filter-mapping/servlet-name","setServletName", 0);
    }

    private void servletRule(Digester digester) {
        //定义servlet 标签的执行流程，开始创建并压入，离开时弹出
        digester.addObjectCreate("web-app/servlet", StandardWrapper.class);
        //取出栈顶的两个元素 0=wrapper 1 = context ,调用context.addChild(wrapper)
        digester.addSetNext("web-app/servlet","addChild", Container.class.getName());
        //调用栈顶元素0 = wrapper.setServletClass
        digester.addCallMethod("web-app/servlet/servlet-class","setServletClass",0);
        digester.addCallMethod("web-app/servlet/servlet-name","setName",0);
        //.. 离开 servlet，就会执行WrapperCreateRule.end() 会把wrapper弹出
        //遇到servlet-mapping 调用context的对应方法
        digester.addCallMethod("web-app/servlet-mapping","addServletMapping",2);
        digester.addCallParam("web-app/servlet-mapping/servlet-name", 1);
        digester.addCallParam("web-app/servlet-mapping/url-pattern", 0);
    }
}
